# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name:        textparser.py
# Purpose:     Обработки текста на основе списка регулярных выражений.
#
# Author:      Yegor Chemisov <yegor.chemisov@gmail.com>
#
# Created:     29.04.2011
# Copyright:   (c) Yegor Chemisov 2011
# Licence:     GNU GPL v3
#-------------------------------------------------------------------------------

import re
import configparser
import glob
import os

CONFIG_FILE_ENCODING = 'utf_8_sig'
# Кодировка текста используемая в конфигурационных файлах

class ProcessingRules:
    """class ProcessingRules
    Класс предназначен для обработки текста на основе списка регулярных
    выражений. Правила обработки текста считываются из конфигурационного файла
    имеющего секции: Input, Output, Options."""
    footnotesNr = 0

    def __init__(self, configFile, flag = re.DOTALL | re.MULTILINE):
        self.output = { 'fb2_footnote': self.fb2_footnote,
                        'fb2_footnote_text': self.fb2_footnote_text }
        self.config = configparser.ConfigParser()
        self.config.read(configFile, encoding = CONFIG_FILE_ENCODING)
        self.regexps = [(key, re.compile(value, flag))
           for key, value in self.config['Input'].items()]
        self.output.update(dict(self.config['Output']))
        self.footnotes = self.config['Options']['Notes'] \
            if self.config.has_option('Options', 'Notes') else ''

    def processText(self, text):
        for key, regexp in self.regexps:
            #if key[0] == '_': print(key, regexp.findall(text))
            text = regexp.sub(self.output[key], text)
        return text

    def fb2_footnote(self, match):
        return self.config['Options']['Footnote'].format(
            self.footnotesNr + int(match.group(1)))

    def fb2_footnote_text(self, match):
        self.footnotesNr += 1
        self.footnotes += self.config['Options']['FootText'].format(
            self.footnotesNr, match.group(2))
        return ''

class TextParser:
    ''' Этот класс не завершён
    '''

    def __init__(self, configFile):
        self.config = configparser.ConfigParser()
        self.config.read(configFile, encoding = CONFIG_FILE_ENCODING)

    def carryOut(self, taskName, functions = None):
        task = self.config[taskName]
        print ('Processing Rules: ', task['Processing Rules'])
        rules = ProcessingRules(task['Processing Rules'])
        if functions: rules.output.update(functions)

        sourceText = [(os.path.splitext(os.path.basename(file))[0],
                open(file, 'r', encoding=task['Source encoding']).read())
                for file in glob.glob(task['Source files'])]

        separator = task['Split'] if 'Split' in task.keys() else None
        if separator: sourceText = \
            [(a, c) for a, b in sourceText for c in b.split(separator)]

        outputText = [(file, rules.processText(text))
                for file, text in sourceText]
        if rules.footnotes:
            outputText.append(('footnotes', rules.footnotes))

        template = open(task['Output template'], 'r',
            encoding=task['Output encoding']).read()
        print ('Template:', task['Output template'])

        if task['Output format'] in ('fb2', 'xdxf'):
            text = ''.join([data for file, data in outputText])
            open(task['Output Directory'] + task['Output filename'], 'w',
                encoding=task['Output encoding']).write(
                template % text)
        if task['Output format'] in ('epub', 'mobi'):
            fileId = 0
            for file, text in outputText:
                fileId += 1
                fileName = 'page-{0:d}'.format(fileId) if separator else file
                open(task['Output Directory'] + fileName
                    + task['Output Extension'], 'w',
                    encoding=task['Output Encoding']).write(template % text)

        print ('Done!')

def main():
    print (ProcessingRules.__doc__)

if __name__ == '__main__':
    main()
